package com.yungu.swift.order.helper;

import com.alibaba.dubbo.config.annotation.Reference;
import com.yungu.swift.assets.driver.model.dto.CarModelValuationDto;
import com.yungu.swift.assets.driver.model.vo.DriverVo;
import com.yungu.swift.assets.driver.service.CarModelValuationService;
import com.yungu.swift.assets.driver.service.DriverService;
import com.yungu.swift.assets.passenger.model.dto.PassengerDto;
import com.yungu.swift.assets.passenger.model.vo.PassengerVo;
import com.yungu.swift.assets.passenger.service.PassengerService;
import com.yungu.swift.autoconfig.redis.RedisCacheService;
import com.yungu.swift.base.ResponseData;
import com.yungu.swift.constants.CommonConstant;
import com.yungu.swift.lbs.model.Coordinate;
import com.yungu.swift.lbs.model.DriverLocation;
import com.yungu.swift.lbs.model.DriverPoint;
import com.yungu.swift.lbs.model.dto.LatLngDto;
import com.yungu.swift.lbs.model.vo.DrivingNearestVo;
import com.yungu.swift.lbs.service.DistanceService;
import com.yungu.swift.lbs.service.LocationService;
import com.yungu.swift.order.dao.OrderDetailMapper;
import com.yungu.swift.order.dao.OrderMapper;
import com.yungu.swift.order.dao.OrderStaticDataMapper;
import com.yungu.swift.order.model.dto.OrderDetailDto;
import com.yungu.swift.order.model.dto.OrderDto;
import com.yungu.swift.order.model.dto.OrderFareDto;
import com.yungu.swift.order.model.dto.OrderStaticDataDto;
import com.yungu.swift.order.model.param.AdminOrderEditParam;
import com.yungu.swift.order.model.vo.JsonOrderDetailVo;
import com.yungu.swift.order.service.OrderDetailService;
import com.yungu.swift.order.service.OrderFareService;
import com.yungu.swift.order.thread.order.OrderHandleThreadPoolUtil;
import com.yungu.swift.order.utils.CommonUtils;
import com.yungu.swift.order.utils.PolylineUtils;
import com.yungu.swift.socket.communication.message.UploadLocationMessage;
import com.yungu.swift.socket.communication.service.UploadLocationService;
import com.yungu.swift.system.sys.model.dto.SysAccountPassengerDto;
import com.yungu.swift.system.sys.model.dto.SysBusinessOperateLogDto;
import com.yungu.swift.system.sys.model.enums.SysBusinessOperateEnum;
import com.yungu.swift.system.sys.service.SysAccountPassengerService;
import com.yungu.swift.system.sys.service.SysFenceService;
import com.yungu.swift.utils.DateUtils;
import com.yungu.swift.utils.JsonUtils;
import com.yungu.swift.utils.MapUtils;
import com.yungu.swift.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import static com.yungu.swift.constants.OrderConstant.ORDER_JOIN_STATUS_COMPLETED;
import static com.yungu.swift.constants.OrderConstant.ORDER_JOIN_STATUS_PASSENGER_ABOARD;

/**
 * @author : cuixiuyin
 * @date : 2019/5/9
 */
@Slf4j
@Component
public class OrderHelper {

    private static RedisCacheService redisCacheService;
    private static OrderDetailService orderDetailService;
    private static OrderFareService orderFareService;
    private static OrderMapper orderMapper;
    private static OrderDetailMapper orderDetailMapper;
    private static OrderStaticDataMapper orderStaticDataMapper;
    private static LocationService locationService;
    private static UploadLocationService uploadLocationService;
    private static CarModelValuationService carModelValuationService;
    private static PassengerService passengerService;
    private static DriverService driverService;
    private static SysAccountPassengerService sysAccountPassengerService;

    private static SysFenceService sysFenceService;
    private static DistanceService distanceService;

    /**
     * 锁对象
     */
    private static Lock lock = new ReentrantLock();

    /**
     * 订单主动上传定位点方法
     *
     * @param uploadText 定位点报文
     */
    public static boolean uploadTextResult(String uploadText) {
        try {
            //保存点
            if (StringUtils.isNotEmpty(uploadText)) {
                UploadLocationMessage uploadLocationMessage = JsonUtils.readValue(uploadText, UploadLocationMessage.class);
                return uploadLocationService.uploadDriverLocation(uploadLocationMessage).isSuccess();
            }
        } catch (Exception e) {
            log.error("OrderHelper uploadTextResult error. uploadText：{}", uploadText, e);
        }
        return false;
    }

    /**
     * 在订单匹配的时候更新静态信息表
     */
    public static void saveOrUpdateStaticDataOnOrderMatch(OrderDto orderDto) {
        //订单信息不影响主流程 放到线程中保存
        OrderHandleThreadPoolUtil.execute(() -> {
            List<OrderStaticDataDto> list = orderStaticDataMapper.list(MapUtils.build("orderUuid", orderDto.getUuid()));
            //重新获得订单相关数据
            OrderStaticDataDto orderExpandDtoChange = orderStaticDataMapper.getOrderStaticDataByUuid(
                    MapUtils.build("uuid", orderDto.getUuid()));
            if (orderExpandDtoChange != null) {
                if (CollectionUtils.isNotEmpty(list)) {
                    orderExpandDtoChange.setOrderUuid(orderDto.getUuid());
                    orderExpandDtoChange.setUpdateOn(new Date());
                    orderExpandDtoChange.setUpdateBy(orderDto.getUpdateBy());
                    orderStaticDataMapper.updateOrderStaticData(orderExpandDtoChange);
                    return;
                }
                orderExpandDtoChange.setUuid(StringUtils.buildUUID());
                orderExpandDtoChange.setCreateOn(new Date());
                orderExpandDtoChange.setCreateBy(orderDto.getUpdateBy());
                orderExpandDtoChange.setOrderUuid(orderDto.getUuid());
                orderStaticDataMapper.add(orderExpandDtoChange);
            }
        });
    }

    /**
     * 在司机确认费用的时候更新静态信息表
     */
    public static void updateOrderStaticDataOnConfirmFare(OrderFareDto orderFareDto) {
        List<OrderStaticDataDto> list = orderStaticDataMapper.list(MapUtils.build("orderUuid", orderFareDto.getOrderUuid()));
        if (CollectionUtils.isNotEmpty(list)) {
            OrderStaticDataDto orderExpandDto = list.get(0);
            //获取运价信息
            Map<String, Object> map = MapUtils.build(3);
            map.put("uuid", orderFareDto.getCarModelValuationUuid());
            CarModelValuationDto carValuationDto = carModelValuationService.get(map).getData();
            if (carValuationDto != null) {
                OrderStaticDataDto updateOrderStaticData = new OrderStaticDataDto();
                updateOrderStaticData.setUuid(orderExpandDto.getUuid());
                updateOrderStaticData.setOrderUuid(orderExpandDto.getOrderUuid());
                updateOrderStaticData.setCarModelValuationUuid(carValuationDto.getUuid());
                updateOrderStaticData.setCityUuid(carValuationDto.getCityUuid());
                updateOrderStaticData.setCarModelUuid(carValuationDto.getCarModelUuid());
                updateOrderStaticData.setAssignDriverFare(carValuationDto.getAssignDriverFare());
                updateOrderStaticData.setOrderTypeTime(carValuationDto.getOrderTypeTime());
                updateOrderStaticData.setOwnCancelFare(carValuationDto.getOwnCancelFare());
                updateOrderStaticData.setSysCancelFare(carValuationDto.getSysCancelFare());
                updateOrderStaticData.setPremiumOneRate(carValuationDto.getPremiumOneRate());
                updateOrderStaticData.setPremiumOneTime(DateUtils.format(carValuationDto.getPremiumOneStart(),
                        "HH:MM:SS") + "-" + DateUtils.format(carValuationDto.getPremiumOneEnd(), "HH:MM:SS"));
                updateOrderStaticData.setPremiumTwoRate(carValuationDto.getPremiumTwoRate());
                updateOrderStaticData.setPremiumTwoTime(DateUtils.format(carValuationDto.getPremiumTwoStart(),
                        "HH:MM:SS") + "-" + DateUtils.format(carValuationDto.getPremiumTwoEnd(), "HH:MM:SS"));
                updateOrderStaticData.setStartFare(carValuationDto.getStartFare());
                updateOrderStaticData.setStartTrip(carValuationDto.getStartTrip());
                updateOrderStaticData.setStartDuration(carValuationDto.getStartDuration());
                updateOrderStaticData.setBeyondTripFare(carValuationDto.getBeyondTripFare());
                updateOrderStaticData.setBeyondTimeFare(carValuationDto.getBeyondTimeFare());
                updateOrderStaticData.setFreeWaitTime(carValuationDto.getFreeWaitTime());
                updateOrderStaticData.setBeyondWaitFare(carValuationDto.getBeyondWaitFare());
                updateOrderStaticData.setNightTimeStr(DateUtils.format(carValuationDto.getNightTimeStart(),
                        "HH:MM:SS") + "-" + DateUtils.format(carValuationDto.getNightTimeEnd(), "HH:MM:SS"));
                updateOrderStaticData.setNightTripFare(carValuationDto.getNightTripFare());
                updateOrderStaticData.setHaulBackTrip(carValuationDto.getHaulBackTrip());
                updateOrderStaticData.setHaulBackTripFare(carValuationDto.getHaulBackTripFare());
                updateOrderStaticData.setStatus(carValuationDto.getStatus());
                updateOrderStaticData.setUpdateOn(new Date());
                updateOrderStaticData.setUpdateBy(orderFareDto.getUpdateBy());
                orderStaticDataMapper.updateOrderStaticData(updateOrderStaticData);
            }
        }
    }


    public static String orderReportInfo(JsonOrderDetailVo jsonOrderDetailVo) {
        //播报内容
        StringBuffer report = new StringBuffer();
        if (jsonOrderDetailVo.getTypeTime().compareTo(CommonConstant.TYPE_TIME_REAL_TIME) == 0) {
            DriverPoint driverPoint = locationService.findDriverPoint(jsonOrderDetailVo.getActualDriverUuid(),
                    jsonOrderDetailVo.getAppid()).getData();
            if (driverPoint != null) {
                report.append("实时单,距您#");
                Double distance = getAssignDistance(jsonOrderDetailVo, driverPoint);
                //里程为0时 重新调用一次
                if (distance == 0) {
                    log.info("订单{}查询司机与乘客距离为0，重新调用高德", jsonOrderDetailVo.getOrderNo());
                    distance = getAssignDistance(jsonOrderDetailVo, driverPoint);
                }
                if (distance > 1000) {
                    report.append(distance / 1000);
                    report.append("公里#,");
                } else {
                    report.append(distance);
                    report.append("米#,");
                }
            } else {
                report.append("实时单,");
            }
        }
        if (jsonOrderDetailVo.getTypeTime().compareTo(CommonConstant.TYPE_TIME_APPIONT) == 0) {
            report.append("预约单,");
        }
        if (jsonOrderDetailVo.getTypeTime().compareTo(CommonConstant.TYPE_TIME_SEND_AIRPORT) == 0) {
            report.append("送机,");
        }
        if (jsonOrderDetailVo.getTypeTime().compareTo(CommonConstant.TYPE_TIME_MEET_AIRPORT) == 0) {
            report.append("接机,");
        }
        if (jsonOrderDetailVo.getTypeTime().compareTo(CommonConstant.TYPE_TIME_DAILY_RENTAL) == 0
                || jsonOrderDetailVo.getTypeTime().compareTo(CommonConstant.TYPE_TIME_HALF_DAILY_RENTAL) == 0) {
            report.append(jsonOrderDetailVo.getTitle() + ",");
        }
        if (jsonOrderDetailVo.getTip() != null) {
            // 如果确定是整数，可以使用其他方式
            // 而且此方法固定了名称是"空驶费"，是否合适？别的订单类型？别的名称？
            String surcharge = jsonOrderDetailVo.getTip().toString();
            int surchargeInteger = Integer.parseInt(surcharge.replace(".00", "").replace(".0", ""));
            if (surchargeInteger > 0) {
                report.append("调度费").append(surchargeInteger).append("元,");
            }
        }
        if (jsonOrderDetailVo.getTypeTime().compareTo(CommonConstant.TYPE_TIME_APPIONT) == 0
                || jsonOrderDetailVo.getTypeTime().compareTo(CommonConstant.TYPE_TIME_SEND_AIRPORT) == 0
                || jsonOrderDetailVo.getTypeTime().compareTo(CommonConstant.TYPE_TIME_MEET_AIRPORT) == 0) {
            report.append(translateDate(jsonOrderDetailVo.getDeparTime().getTime()));
        }
        report.append("从").append(CommonUtils.getCounty(jsonOrderDetailVo.getOriginDetailAddress())
                + jsonOrderDetailVo.getOriginAddress());
        //过滤包车目的地
        if (jsonOrderDetailVo.getTypeTrip().compareTo(CommonConstant.NEW_ORDER_TYPE_TRIP_DAILY) != 0 && jsonOrderDetailVo.getTypeTrip().compareTo(CommonConstant.NEW_ORDER_TYPE_TRIP_HALF) != 0) {
            report.append("到").append(CommonUtils.getCounty(jsonOrderDetailVo.getDestDetailAddress()) + jsonOrderDetailVo.getDestAddress());
        }
        if (jsonOrderDetailVo.getTypeTime().compareTo(CommonConstant.TYPE_TIME_REAL_TIME) == 0) {
            if (jsonOrderDetailVo.getTypeTrip().compareTo(CommonConstant.BUSINESS_TYPE_TAXI) == 0) {
                report.append("的订单");
            } else {
                report.append("的订单，请尽快联系乘客,前往上车地点。您辛苦了，路上注意安全！");
            }
        }

        //预约单增加里程播报
        boolean falg = CommonConstant.BUSINESS_TYPE_TAXI != jsonOrderDetailVo.getTypeTrip()
                && CommonConstant.BUSINESS_TYPE_POOL != jsonOrderDetailVo.getTypeModule()
                && CommonConstant.BUSINESS_TYPE_PARCEL != jsonOrderDetailVo.getTypeModule()
                && (jsonOrderDetailVo.getTypeTime().compareTo(CommonConstant.TYPE_TIME_APPIONT) == 0
                || jsonOrderDetailVo.getTypeTime().compareTo(CommonConstant.TYPE_TIME_SEND_AIRPORT) == 0)
                && jsonOrderDetailVo.getTypeTrip() != CommonConstant.NEW_ORDER_TYPE_TRIP_DAILY
                && jsonOrderDetailVo.getTypeTrip() != CommonConstant.NEW_ORDER_TYPE_TRIP_HALF;
        if (falg) {
            report.append(",全程预计:").append(jsonOrderDetailVo.getPlanTrip()).append("公里");
        }
        if (StringUtils.isNotEmpty(jsonOrderDetailVo.getRemark())) {
            report.append(",").append(jsonOrderDetailVo.getRemark());
        }
        return report.toString();
    }

    /**
     * 查询派单里程
     *
     * @return
     */
    private static Double getAssignDistance(JsonOrderDetailVo jsonOrderDetailVo, DriverPoint driverPoint) {
        try {
            String originLng = jsonOrderDetailVo.getOriginLng();
            String originLat = jsonOrderDetailVo.getOriginLat();
            String areaLng = String.valueOf(driverPoint.getCoordinate().getLng());
            String areaLat = String.valueOf(driverPoint.getCoordinate().getLat());
            DrivingNearestVo drivingNearest = distanceService.getDrivingNearest(originLng, originLat, areaLng, areaLat).getData();
            log.info("订单{}派单查询司机与乘客距离{},{},{},{},高德返回结果：{}", jsonOrderDetailVo.getOrderNo(),
                    originLng, originLat, areaLng, originLat, drivingNearest.getDistance());
            return drivingNearest.getDistance();
        } catch (Exception e) {
            log.info("订单{}派单查询司机与乘客距离异常", jsonOrderDetailVo.getOrderNo());
            return 0d;
        }
    }

    private static String translateDate(Long time) {
        long oneDay = 24 * 60 * 60 * 1000;
        Calendar current = Calendar.getInstance();
        Calendar today = Calendar.getInstance();
        today.set(Calendar.YEAR, current.get(Calendar.YEAR));
        today.set(Calendar.MONTH, current.get(Calendar.MONTH));
        today.set(Calendar.DAY_OF_MONTH, current.get(Calendar.DAY_OF_MONTH));
        // Calendar.HOUR——12小时制的小时数 Calendar.HOUR_OF_DAY——24小时制的小时数
        today.set(Calendar.HOUR_OF_DAY, 0);
        today.set(Calendar.MINUTE, 0);
        today.set(Calendar.SECOND, 0);
        today.set(Calendar.MILLISECOND, 0);
        Date dt = new Date(time);
        SimpleDateFormat fmt = new SimpleDateFormat("HH:mm");
        String dtStr = fmt.format(dt);
        long todayStartTime = today.getTimeInMillis();
        //业务上只做三天
        if (time >= todayStartTime && time < todayStartTime + oneDay) {
            return "今天" + dtStr;
        } else if (time >= todayStartTime + oneDay && time < todayStartTime + oneDay * 2) {
            return "明天" + dtStr;
        } else if (time >= todayStartTime + oneDay * 2 && time < todayStartTime + oneDay * 3) {
            return "后天" + dtStr;
        } else {
            return "预约时间有误";
        }
    }


    /**
     * 根据订单 uuid 查询订单，用来判断app运营商是否可以操作该订单
     */
    public static OrderDto findOrder(String uuid) {
        if (StringUtils.isEmpty(uuid)) {
            return null;
        }
        List<OrderDto> orderDtos = orderMapper.list(MapUtils.build("uuid", uuid));
        if (CollectionUtils.isEmpty(orderDtos)) {
            return null;
        }
        return orderDtos.get(0);
    }

    /**
     * 根据订单号，订单类型获取订单详情信息
     */
    public static OrderDetailDto findOrderDetail(String orderUuid) {
        if (StringUtils.isEmpty(orderUuid)) {
            return null;
        }
        List<OrderDetailDto> detailDtoList = orderDetailMapper.list(MapUtils.build("orderUuid", orderUuid));
        if (CollectionUtils.isEmpty(detailDtoList)) {
            return null;
        }
        return detailDtoList.get(0);
    }

    /**
     * 保存订单信息，包括订单、订单详情、订单费用详情
     */
    public static String saveOrderInfo(OrderDto orderDto, OrderDetailDto orderDetailDto, OrderFareDto orderFareDto) {
        lock.lock();
        try {
            orderDto = saveOrUpdate(orderDto);
            if (null != orderDto) {
                //保存订单详情表
                orderDetailDto.setOrderUuid(orderDto.getUuid());
                orderDetailService.saveOrUpdate(orderDetailDto);
                //保存订单价格表
                orderFareDto.setOrderUuid(orderDto.getUuid());
                orderFareService.saveOrUpdate(orderFareDto);
            }
        } finally {
            lock.unlock();
        }
        return orderDto.getUuid();
    }

    public static OrderDto saveOrUpdate(OrderDto orderDto) {
        int flag;
        if (StringUtils.isNotEmpty(orderDto.getUuid())) {
            orderDto.setUpdateOn(new Date());
            flag = orderMapper.edit(orderDto);
        } else {
            orderDto.setUuid(StringUtils.buildUUID());
            orderDto.setOrderNo(createOrderNo(orderDto));
            orderDto.setMatchTime(new Date());
            orderDto.setCreateOn(new Date());
            flag = orderMapper.add(orderDto);
        }
        if (flag > 0) {
            return orderDto;
        }
        return null;
    }

    /**
     * 生成订单号
     *
     * @param dto
     * @return
     * @author cuixiuyin
     */
    private synchronized static String createOrderNo(OrderDto dto) {
        return getOrderNoTypeStr(dto.getTypeModule()) + String.format("%02d", dto.getTypeTrip()) + dto.getTypeTime() +
                DateUtils.format(new Date(), "yyyyMMddHHmmssSSS");
    }

    public static boolean isOrderCanceled(Integer orderStatus) {
        return (orderStatus.toString().startsWith("5") && orderStatus != 500);
    }

    /**
     * 根据业务类型 定义订单类型编码
     */
    private static String getOrderNoTypeStr(Integer typeModule) {
        switch (typeModule) {
            case CommonConstant.BUSINESS_TYPE_TAXI: {
                return "CZ";
            }
            case CommonConstant.BUSINESS_TYPE_SPEC: {
                return "ZC";
            }
            case CommonConstant.BUSINESS_TYPE_POOL: {
                return "PC";
            }
            case CommonConstant.BUSINESS_TYPE_EXPRESS: {
                return "KC";
            }
            default: {
                return "UK";
            }
        }
    }

    /**
     * 订单相关业务操作日志构造
     */
    public static SysBusinessOperateLogDto orderOperateBuild(AdminOrderEditParam orderEditParam, OrderDetailDto orderDetailDto, String field) {
        SysBusinessOperateLogDto operateLogDto = new SysBusinessOperateLogDto();
        switch (field) {
            case "passengerNum":
                operateLogDto.setBeforeValue(String.valueOf(orderDetailDto.getActualPasNum()));
                operateLogDto.setAfterValue(String.valueOf(orderEditParam.getPassengerNum()));
                operateLogDto.setOperationCode(SysBusinessOperateEnum.UDP_PASSENGER_NUM.getCode());
                operateLogDto.setOperationName(SysBusinessOperateEnum.UDP_PASSENGER_NUM.getName());
                operateLogDto.setOperationDescribe("客服修改乘客人数");
                break;
            case "deparTime":
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                operateLogDto.setBeforeValue(sdf.format(orderDetailDto.getDeparTime()));
                operateLogDto.setAfterValue(sdf.format(orderEditParam.getDeparTime()));
                operateLogDto.setOperationCode(SysBusinessOperateEnum.UDP_DEPART_TIME.getCode());
                operateLogDto.setOperationName(SysBusinessOperateEnum.UDP_DEPART_TIME.getName());
                operateLogDto.setOperationDescribe("客服修改出发时间");
                break;
            case "originAddress":
                operateLogDto.setBeforeValue(orderDetailDto.getOriginDetailAddress());
                operateLogDto.setAfterValue(orderEditParam.getOriginDetailAddress());
                operateLogDto.setOperationCode(SysBusinessOperateEnum.UDP_ORIGIN_ADDRESS.getCode());
                operateLogDto.setOperationName(SysBusinessOperateEnum.UDP_ORIGIN_ADDRESS.getName());
                operateLogDto.setOperationDescribe("客服修改起点地址");
                break;
            case "destAddress":
                operateLogDto.setBeforeValue(orderDetailDto.getDestDetailAddress());
                operateLogDto.setAfterValue(orderEditParam.getDestDetailAddress());
                operateLogDto.setOperationCode(SysBusinessOperateEnum.UDP_DEST_ADDRESS.getCode());
                operateLogDto.setOperationName(SysBusinessOperateEnum.UDP_DEST_ADDRESS.getName());
                operateLogDto.setOperationDescribe("客服修改目的地址");
                break;
            case "orderRemark":
                operateLogDto.setBeforeValue(orderDetailDto.getRemark());
                operateLogDto.setAfterValue(orderEditParam.getRemark());
                operateLogDto.setOperationCode(SysBusinessOperateEnum.UDP_ORDER_REMARK.getCode());
                operateLogDto.setOperationName(SysBusinessOperateEnum.UDP_ORDER_REMARK.getName());
                operateLogDto.setOperationDescribe("客服修改订单备注");
                break;
            case "returnVisit":
                operateLogDto.setBeforeValue("未回访");
                operateLogDto.setAfterValue("已回访");
                operateLogDto.setOperationCode(SysBusinessOperateEnum.ORDER_RETURN_VISIT.getCode());
                operateLogDto.setOperationName(SysBusinessOperateEnum.ORDER_RETURN_VISIT.getName());
                operateLogDto.setOperationDescribe("客服首单回访");
                break;
            default:
                break;
        }
        operateLogDto.setCreateBy(orderEditParam.getUserUuid());
        operateLogDto.setCreateOn(new Date());
        operateLogDto.setAgentUuid(orderEditParam.getUserAgentUuid());
        operateLogDto.setCompanyUuid(orderEditParam.getUserCompanyUuid());
        operateLogDto.setAppid(orderEditParam.getAppid());
        operateLogDto.setUuid(StringUtils.buildUUID());
        operateLogDto.setOperationUserIp(orderEditParam.getUserip());
        return operateLogDto;
    }

    /**
     * 是否火车站订单
     *
     * @param orderDetailDto
     */
    public static boolean isStationOrder(OrderDetailDto orderDetailDto) {
        //校验起点是否在火车站围栏中
        ResponseData statusRsd = sysFenceService.checkInFence(orderDetailDto.getOriginCityUuid(), orderDetailDto.getOriginLng(), orderDetailDto.getOriginLat(), CommonConstant.FENCE_PURPOSE_STATION);
        if (statusRsd.isSuccess()) {
            log.info("订单{}起点进入火车站围栏", orderDetailDto.getOrderUuid());
            return true;
        }
        //校验终点是否在火车站围栏中
        statusRsd = sysFenceService.checkInFence(orderDetailDto.getDestCityUuid(), orderDetailDto.getDestLng(), orderDetailDto.getDestLat(), CommonConstant.FENCE_PURPOSE_STATION);
        if (statusRsd.isSuccess()) {
            log.info("订单{}终点进入火车站围栏", orderDetailDto.getOrderUuid());
            return true;
        }
        log.info("订单{}未进入火车站围栏", orderDetailDto.getOrderUuid());
        return false;
    }


    /**
     * 补充订单详情相关信息
     */
    public static void fillOrderInfo(JsonOrderDetailVo jsonOrderDetailVo) {
        PassengerDto passengerDto = passengerService.get(jsonOrderDetailVo.getPassengerUuid()).getData();
        if (passengerDto != null) {
            PassengerVo passenger = new PassengerVo();
            BeanUtils.copyProperties(passengerDto, passenger);
            //获取乘客钱包信息
            ResponseData<SysAccountPassengerDto> responseData = sysAccountPassengerService.get(passengerDto.getUuid());
            if (responseData.isSuccess() && null != responseData.getData()) {
                SysAccountPassengerDto accountPassengerDto = responseData.getData();
                BigDecimal balance = accountPassengerDto.getRechargeBalance().add(accountPassengerDto.getPresentBalance());
                passenger.setBalance(balance.doubleValue());
            }
            jsonOrderDetailVo.setPassenger(passenger);
        }
        if (StringUtils.isNotEmpty(jsonOrderDetailVo.getActualDriverUuid())) {
            DriverVo driverVo = driverService.selInfo(jsonOrderDetailVo.getActualDriverUuid()).getData();
            if (driverVo != null) {
                jsonOrderDetailVo.setDriver(driverVo);
            }
        }
    }

    /**
     * 跨城订单获取i定位点
     */
    public static String getCrosstownTracePoint(JsonOrderDetailVo jsonOrderDetailVo) {
        //先从缓存中取
        String redisTracePointsKey = "crosstownOrderPointKey" + jsonOrderDetailVo.getOrderUuid();
        Object tracePoints = redisCacheService.get(redisTracePointsKey);
        if (tracePoints != null) {
            return tracePoints.toString();
        }
        Map<String, Object> paraMap = new HashMap<>();
        paraMap.put("mainOrderUUid", jsonOrderDetailVo.getMainOrderUuid());
        paraMap.put("appid", jsonOrderDetailVo.getAppid());
        List<DriverLocation> driverLocationList = locationService.getCrosstownOrderLocation(paraMap).getData();

        List<LatLngDto> pointList = new ArrayList<>();
        boolean isStart = false;
        for (DriverLocation driverLocation : driverLocationList) {
            if (jsonOrderDetailVo.getOrderUuid().equals(driverLocation.getOrderUuid())
                    && driverLocation.getJoinStatus() == ORDER_JOIN_STATUS_PASSENGER_ABOARD) {
                isStart = true;
            } else if (jsonOrderDetailVo.getOrderUuid().equals(driverLocation.getOrderUuid())
                    && driverLocation.getJoinStatus() == ORDER_JOIN_STATUS_COMPLETED) {
                setPointList(pointList, driverLocation.getCoordinate());
                break;
            }
            if (isStart) {
                setPointList(pointList, driverLocation.getCoordinate());
            }
        }
        if (CollectionUtils.isNotEmpty(pointList)) {
            return PolylineUtils.encodePoly(pointList);
        }
        return null;
    }

    /**
     * 设置定位点集合
     */
    private static void setPointList(List<LatLngDto> list, Coordinate coordinate) {
        LatLngDto latLngDto = new LatLngDto();
        latLngDto.setLatitude(coordinate.getLat());
        latLngDto.setLongitude(coordinate.getLng());
        list.add(latLngDto);
    }


    @Autowired
    public void setRedisCacheService(RedisCacheService redisCacheService) {
        OrderHelper.redisCacheService = redisCacheService;
    }

    @Autowired
    public void setOrderDetailService(OrderDetailService orderDetailService) {
        OrderHelper.orderDetailService = orderDetailService;
    }

    @Autowired
    public void setOrderFareService(OrderFareService orderFareService) {
        OrderHelper.orderFareService = orderFareService;
    }

    @Autowired
    public void setOrderMapper(OrderMapper orderMapper) {
        OrderHelper.orderMapper = orderMapper;
    }

    @Autowired
    public void setOrderDetailMapper(OrderDetailMapper orderDetailMapper) {
        OrderHelper.orderDetailMapper = orderDetailMapper;
    }

    @Autowired
    public void setOrderStaticDataMapper(OrderStaticDataMapper orderStaticDataMapper) {
        OrderHelper.orderStaticDataMapper = orderStaticDataMapper;
    }

    @Reference
    public void setUploadLocationService(UploadLocationService uploadLocationService) {
        OrderHelper.uploadLocationService = uploadLocationService;
    }

    @Reference
    public void setCarModelValuationService(CarModelValuationService carModelValuationService) {
        OrderHelper.carModelValuationService = carModelValuationService;
    }

    @Reference
    public void setPassengerService(PassengerService passengerService) {
        OrderHelper.passengerService = passengerService;
    }

    @Reference
    public void setDriverService(DriverService driverService) {
        OrderHelper.driverService = driverService;
    }

    @Reference
    public void setSysAccountPassengerService(SysAccountPassengerService sysAccountPassengerService) {
        OrderHelper.sysAccountPassengerService = sysAccountPassengerService;
    }

    @Reference
    public void setLocationService(LocationService locationService) {
        OrderHelper.locationService = locationService;
    }

    @Reference
    public void setSysFenceService(SysFenceService sysFenceService) {
        OrderHelper.sysFenceService = sysFenceService;
    }

    @Reference
    public void setDistanceService(DistanceService distanceService) {
        OrderHelper.distanceService = distanceService;
    }
}
